package helper.scxml.scxml2.t0.case2_traffic.zone.ts

import helper.base.BaseTypeHelper.toIntRange
import helper.base.LHMHelper.A2LHMExpand.add
import helper.base.debug.DebugHelper.DebuggerList.Companion.makeDebuggerList
import helper.base.debug.DebugRes.d_t_pT1Calculate_path
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.aStart
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.aTrainWait
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.bike
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.getSimpleT1EnvStrategy
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.train
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.trainWaitBack
import helper.scxml.scxml2.t0.case2_traffic.zone.TrafficEnvHelper.StrategyObj.trainWaitTrain
import helper.scxml.scxml2.t0.case2_traffic.zone.ts.T0Helper.TaskUnit.Companion.getTaskUnit
import helper.scxml.strategy.TotalStrategyHelper.KREWTuple.Companion.makeKREWTuple
import helper.scxml.strategy.TotalStrategyHelper.SNode.Companion.makeSNode
import helper.scxml.strategy.sNodeUnit.T2SNodeUnitHelper.ERT2SNodeUnit.Companion.makeL0ERT2SNodeUnit
import helper.scxml.strategy.sNodeUnit.T2SNodeUnitHelper.SubT2SNodeUnit.Companion.makeSubT2SNodeUnit
import helper.scxml.strategy.sNodeUnit.T2SNodeUnitHelper.T2SNodeUnit
import org.junit.Test

internal class T3_trainOne_byTime_simple {
    fun getT3T2SNodeUnit(): T2SNodeUnit {
        return makeL0ERT2SNodeUnit(
            env = getSimpleT1EnvStrategy(),
            ren = makeSubT2SNodeUnit().apply {
                relationLHM.add(
                    null,
                    aStart,
                    makeSNode().also { aSNode ->
                        funLHM.add(aSNode) {
                            val enterS0Time = it.byNameFindC("t").getPointD()
                            if (enterS0Time <= 2) {
                                "t<=2"
                            } else {
                                "t>2"
                            }
                        }
                        arrayOf(
                            makeKREWTuple("t<=2", 1.toIntRange(), train, 1),
                            makeKREWTuple("t>2", 1.toIntRange(), bike, 1),
                        ).forEach {
                            addSNode(aSNode, it)
                        }
                    },
                )
                relationLHM.add(
                    null,
                    aTrainWait,
                    makeSNode().also { aSNode ->
                        funLHM.add(aSNode) {
                            val enterS0Time = it.byNameFindC("t").getPointD()
                            if (enterS0Time <= 2) {
                                "t<=2"
                            } else {
                                "t>2"
                            }
                        }
                        arrayOf(
                            makeKREWTuple("t<=2", 1.toIntRange(), trainWaitTrain, 1),
                            makeKREWTuple("t>2", 1.toIntRange(), trainWaitBack, 1),
                        ).forEach {
                            addSNode(aSNode, it)
                        }
                    },
                )
            },
        )
    }

    private val taskUnit = getTaskUnit(getT3T2SNodeUnit())

    @Test
    fun t1() {
        taskUnit.repeatRandomRun(
            1000,
            makeDebuggerList(),
        )
    }
    //repeatTimes = 1000
    //average t = 42.108

    @Test
    fun t3() {
        taskUnit.t1Cal(
            makeDebuggerList(
                d_t_pT1Calculate_path,
            )
        )
    }
    //result={t=41.954545454545446, r=0.09090909090909091}
}